package com.code.app.db;

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.util.ArrayMap;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

public class DaoSupport<T> implements IDaoSupport<T> {

    private final String TAG = "DaoSupport";

    private SQLiteDatabase sqLiteDatabase;

    private Class<T> cls;

    private static final Map<String, Method> contentValuesPutMap = new ArrayMap();

    @Override
    public void init(SQLiteDatabase sqLiteDatabase, Class<T> cls) {
        this.sqLiteDatabase = sqLiteDatabase;
        this.cls = cls;
        //如果表不存在就直接创建
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("create table if not exists ")
                .append(DaoUtils.getTableName(this.cls))
                .append(" (")
                .append("id integer primary key autoincrement, ");

        Field[] fields = this.cls.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String name = field.getName();
            String type = field.getType().getSimpleName();
            stringBuilder.append(name).append(DaoUtils.getColumnType(type)).append(", ");
        }
        stringBuilder.replace(stringBuilder.length() - 2, stringBuilder.length(), ")");
        String createTabelAql = stringBuilder.toString();
        Log.i(TAG, createTabelAql);
        this.sqLiteDatabase.execSQL(createTabelAql);
    }

    @Override
    public List<T> query() {
        return null;
    }

    @Override
    public int delete(String whereClause, String[] whereArgs) {
        return sqLiteDatabase.delete(DaoUtils.getTableName(this.cls), whereClause, whereArgs);
    }

    @Override
    public int update(T obj, String whereClause, String... whereArgs) {
        ContentValues contentValues = contentValuesByObj(obj);
        return sqLiteDatabase.update(DaoUtils.getTableName(this.cls), contentValues, whereClause, whereArgs);
    }


    @Override
    public long insert(T t) {
        ContentValues contentValues = contentValuesByObj(t);
        return this.sqLiteDatabase.insert(DaoUtils.getTableName(this.cls), null, contentValues);
    }

    @Override
    public void insert(List<T> list) {
        sqLiteDatabase.beginTransaction();
        for (T t : list) {
            insert(t);
        }
        sqLiteDatabase.setTransactionSuccessful();
        sqLiteDatabase.endTransaction();
    }

    public ContentValues contentValuesByObj(T o) {
        ContentValues contentValues = new ContentValues();
        Field[] fields = this.cls.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                String name = field.getName();
                Object value = field.get(o);

                String fieldTypeStr = value.getClass().getSimpleName();
                Method putMethod = contentValuesPutMap.get(fieldTypeStr);
                if (putMethod == null) {
                    putMethod = ContentValues.class.getDeclaredMethod("put", String.class, value.getClass());
                    contentValuesPutMap.put(fieldTypeStr, putMethod);
                }
                putMethod.invoke(contentValues, name, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return contentValues;
    }

}
